Skip to content

Fix rootdir conftest fixtures not visible to items collected outside the rootdir#14694

Merged
RonnyPfannschmidt merged 3 commits into
pytest-dev:mainfrom
breidenbach0:fix/doctest-namespace-not-loaded-outside-rootdir
Jul 24, 2026
Merged

Fix rootdir conftest fixtures not visible to items collected outside the rootdir#14694
RonnyPfannschmidt merged 3 commits into
pytest-dev:mainfrom
breidenbach0:fix/doctest-namespace-not-loaded-outside-rootdir

Conversation

@breidenbach0

Copy link
Copy Markdown
Contributor

Problem

Fixes #14683.

doctest_namespace injections (and any fixture defined in the rootdir conftest) stopped being available in pytest 9.1 when --rootdir points to a subdirectory and tests/doctests are collected from a parent directory. Doctests then fail with NameError, e.g. the reporter's invocation:

pytest --rootdir src/xclim/testing --config-file=src/xclim/testing/conftest.py \
       --doctest-modules src/xclim

Reproduced: 9.0.3 passes, 9.1.1 fails with NameError: name '...' is not defined.

Cause

Bisected to 46478fad5 (#14098, pytest 9.1), which changed conftest fixture visibility from nodeid-based to node-based:

  • Before 9.1: a conftest located in the rootdir got an empty baseid (relative to rootdir), which matches every collected item — its fixtures were visible session-wide.
  • After 9.1: that conftest is scoped to its own Directory node. When items are collected from outside the rootdir, that Directory is a sibling subtree, not an ancestor of the items, so the fixtures are no longer visible.

Fix

Restore the pre-9.1 behavior by attaching the rootdir conftest to the Session node, in the two places a conftest gets parsed:

  1. _flush_pending_conftests_to_session — also flush the initial rootdir conftest (e.g. when it is the --config-file) to the Session.
  2. pytest_make_collect_report — when collecting the rootdir Directory, attach its conftest to the Session instead of the Directory.

This is safe:

  • Behavior-identical for normal layouts (everything under the rootdir): the Session is an ancestor of all items, so visibility is unchanged.
  • Preserves Conftest fixtures leak to sibling directories when testpaths points outside rootdir #14004: only the rootdir conftest is affected; nested conftests still scope to their own Directory, so sibling-leak does not return.
  • Fixture overrides still work: a subdir conftest remains more specific than the Session per is_visibility_more_specific, so it still wins.

Tests

  • testing/test_conftest.py::test_rootdir_conftest_visible_outside_rootdir
  • testing/test_doctest.py::TestDoctestNamespaceFixture::test_namespace_fixture_from_rootdir_when_modules_outside_rootdir (mirrors the reporter's exact --config-file + collect-from-parent pattern)

Both fail on main and pass with this change. Added news fragment changelog/14683.bugfix.rst.

Note on #14635

#14635 (Home Assistant, "fixtures not found when a parent directory appears multiple times in an argument list") is tracked as a duplicate and is being worked on separately by @RonnyPfannschmidt (multiple Directory nodes for the same path). This PR targets the rootdir-conftest visibility facet (#14683) only; making the rootdir conftest Session-visible also makes it more robust against the multi-node scenario, but it is not meant to be the complete fix for #14635.

…#14683)

A conftest located in the rootdir used to get an empty baseid (matching
every collected item), so its fixtures were visible session-wide. The
node-based scoping introduced in 46478fa (pytest-dev#14098, pytest 9.1) scoped it
to its own Directory node instead. When --rootdir points to a subdirectory
and tests/doctests are collected from a parent directory, that Directory is
not an ancestor of the collected items, so the conftest fixtures --
including doctest_namespace injections -- became invisible (NameError in
doctests).

Restore the pre-9.1 behavior by attaching the rootdir conftest to the
Session node, in both places a conftest is parsed: the initial-conftest
flush and the Directory collect report.

This is behavior-identical for normal layouts (the Session is an ancestor
of all items under the rootdir), preserves the pytest-dev#14004 sibling-leak fix,
and keeps fixture overrides working (a subdir conftest is still more
specific than the Session).
@psf-chronographer psf-chronographer Bot added the bot:chronographer:provided (automation) changelog entry is part of PR label Jul 11, 2026
@breidenbach0

Copy link
Copy Markdown
Contributor Author

Heads up on the two red CI jobs — both are a known repo-wide infra issue, unrelated to this change:

  • build (ubuntu-pypy3-xdist) fails during dependency installation (before any pytest code runs) while building hypothesis 6.156.6 from source:
    error: the configured PyPy interpreter version (3.10) is lower than PyO3's minimum supported version (3.11)
    
    The latest hypothesis now ships Rust extensions via maturin/pyo3 0.29, and pyo3 0.29 dropped Python 3.10 while the PyPy CI image is on 3.10. Since hypothesis is pinned only as >=3.56, pip pulls the incompatible latest.
  • check is just the re-actors/alls-green status gate — it fails solely as a downstream consequence of the pypy3-xdist failure.

For confirmation, another currently-open PR (#14693, unrelated) fails the identical two jobs with the same cause. All other jobs on this PR (macOS/Ubuntu, Python 3.10–3.15, xdist, plugins, doctesting, etc.) are green.

…ce-not-loaded-outside-rootdir

# Conflicts:
#	testing/test_conftest.py
@breidenbach0
breidenbach0 force-pushed the fix/doctest-namespace-not-loaded-outside-rootdir branch from 69782a0 to 3258779 Compare July 22, 2026 16:35
@RonnyPfannschmidt

Copy link
Copy Markdown
Member

reopend to trigger flaky ci/codecov

@RonnyPfannschmidt
RonnyPfannschmidt merged commit ef052d0 into pytest-dev:main Jul 24, 2026
68 checks passed
@breidenbach0

Copy link
Copy Markdown
Contributor Author

Hello, I was wondering, if I would be able to take up commit access to pytest-dev. Happy to keep going through the usual review process for my own PRs and to start helping others.

Best regards,
breidenbach0

@RonnyPfannschmidt

Copy link
Copy Markdown
Member

that privilege and responsibility is not something to ask for after one pr merged and one pr in the pipeline

it is something we propose to individuals after a trusting relationship has been built - and not all of those take it up

@breidenbach0

Copy link
Copy Markdown
Contributor Author

Ah sorry, I missunderstood the Contributor guidelines. Thanks for clarifying. Looking forward to build that relationship and continue building

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:chronographer:provided (automation) changelog entry is part of PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Variables injected in doctest_namespace no longer loaded in Pytest 9.1.x

3 participants